﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
using Newtonsoft.Json;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Data;
using WxSDK.CacheSys;
using WxSDK.Common;

namespace WxSDK
{

    /// <summary>
    /// 微信用到的通用函数
    /// </summary>
    public class WeChatCommon
    {
        #region 写文件日志
        /// <summary>
        /// 测试-写文件
        /// <para>尽量不要使用</para>
        /// </summary>
        /// <param name="msgs">要写入的数据</param>
        public static void WirteFile(string msgs)
        {
            /*--------写文件,测试有无数据----------*/
            string filepath = System.Web.HttpContext.Current.Server.MapPath("~/log.txt");
            bool IsHas = File.Exists(filepath);
            if (IsHas)
            {
                StreamWriter sw = new StreamWriter(filepath, true);
                sw.WriteLine(msgs + " , " + DateTime.Now.ToString());
                sw.Close();
            }
            else
            {
                FileStream fs = new FileStream(filepath, FileMode.Append);
                fs.Close();
                bool IsCreate = File.Exists(filepath);
                if (IsCreate)
                {
                    StreamWriter sw = new StreamWriter(filepath, true);
                    sw.WriteLine(msgs + " , " + DateTime.Now.ToString());
                    sw.Close();
                }
                else
                {
                    StreamWriter sw = new StreamWriter(filepath, true);
                    sw.WriteLine(DateTime.Now.ToString() + ",失败");
                    sw.Close();
                }
            }
            /*--------写文件,测试有无数据----------*/
        }

        //public static void 
        /// <summary>
        /// 记录日志
        /// <para>尽量不要使用</para>
        /// </summary>
        /// <param name="log">要写入的数据</param>
        public static void WeChatLog(string log)
        {
            /*--------写文件----------*/
            string filepath = System.Web.HttpContext.Current.Server.MapPath("~/WeChatResult.txt");
            bool IsHas = File.Exists(filepath);
            if (IsHas)
            {
                StreamWriter sw = new StreamWriter(filepath, true);
                sw.WriteLine(log + " , " + DateTime.Now.ToString());
                sw.Close();
            }
            else
            {
                FileStream fs = new FileStream(filepath, FileMode.Append);
                fs.Close();
                bool IsCreate = File.Exists(filepath);
                if (IsCreate)
                {
                    StreamWriter sw = new StreamWriter(filepath, true);
                    sw.WriteLine(log + " , " + DateTime.Now.ToString());
                    sw.Close();
                }
                else
                {
                    StreamWriter sw = new StreamWriter(filepath, true);
                    sw.WriteLine(DateTime.Now.ToString() + ",失败");
                    sw.Close();
                }
            }
            /*--------写文件----------*/
        }

        /// <summary>
        /// 写日志  
        /// <para>尽量不要使用</para>
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="cont"></param>
        public static void Log(string filename, string cont) {
            System.IO.File.WriteAllText(HttpContext.Current.Server.MapPath("~/" + filename + ".txt"), cont);
        }
        #endregion

        /// <summary>
        /// 获取随机数
        /// 
        /// </summary>
        /// <returns></returns>
        public static string GetRandom()
        {
            return new Random(BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0)).Next().ToString();
        }

        /// <summary>
        /// 微信 Xml转化为Model
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xml"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public static T XmlToModel<T>(string xml, T model)
        {
            xml = xml.Replace("xml", typeof(T).Name);
            StringReader xmlReader = new StringReader(xml);
            XmlSerializer xmlSer = new XmlSerializer(typeof(T));
            return (T)xmlSer.Deserialize(xmlReader);
        }
        public static void WriteSession(string strName, object strValue)
        {
            HttpContext.Current.Session[strName] = strValue;
        }
        public static object ReadSession(string strName)
        {
            if (HttpContext.Current.Session[strName] != null)
            {
                return HttpContext.Current.Session[strName];
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// 获取订单号
        /// </summary>
        /// <returns></returns>
        public static string GetOrderNum() {
            return DateTime.Now.ToString("yyyyMMddHHmmssfff").ToString();
        }

        /// <summary>
        /// 获取当前web程序的路径 
        /// </summary>
        /// <returns></returns>
        public static string GetCurrDir()
        {
            return System.AppDomain.CurrentDomain.BaseDirectory;
        }

        #region 时间戳转换
        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式
        /// </summary>
        /// <returns>Unix时间戳格式</returns>
        public static long ConvertDateTimeInt()
        {
            return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }
        /// <summary>
        /// 将时间戳转化为现在时间
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static DateTime ConvertIntDateTime(string time)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(time + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }
        #endregion

        #region HTTP请求类
        public static string HttpGet(String url)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "GET";
            request.Accept = "*/*";
            request.Timeout = 15000;
            request.AllowAutoRedirect = false;

            WebResponse response = null;
            string responseStr = null;

            try
            {
                response = request.GetResponse();

                if (response != null)
                {
                    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    responseStr = reader.ReadToEnd();
                    reader.Close();
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                request = null;
                response = null;
            }

            return responseStr;
        }
        public static string HttpPost(string url, string param)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.Accept = "*/*";
            request.Timeout = 15000;
            request.AllowAutoRedirect = false;

            StreamWriter requestStream = null;
            WebResponse response = null;
            string responseStr = null;

            try
            {
                requestStream = new StreamWriter(request.GetRequestStream());
                requestStream.Write(param);
                requestStream.Close();

                response = request.GetResponse();
                if (response != null)
                {
                    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    responseStr = reader.ReadToEnd();
                    reader.Close();
                }
            }
            catch (Exception)
            {
                throw;
            }
            return responseStr;
        }
        public static string HttpPost(String url)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.Accept = "*/*";
            request.Timeout = 15000;
            request.AllowAutoRedirect = false;

            StreamWriter requestStream = null;
            WebResponse response = null;
            string responseStr = null;

            try
            {
                requestStream = new StreamWriter(request.GetRequestStream());
                //requestStream.Write();
                requestStream.Close();

                response = request.GetResponse();
                if (response != null)
                {
                    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    responseStr = reader.ReadToEnd();
                    reader.Close();
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                request = null;
                requestStream = null;
                response = null;
            }

            return responseStr;
        }
        #endregion

        public static string SerializeObject(object obj)
        {
            string result = string.Empty;
            using (MemoryStream stream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);

                byte[] byt = new byte[stream.Length];
                byt = stream.ToArray();
                result = Convert.ToBase64String(byt);
                stream.Flush();
            }
            return result;
        }
        public static object DeserializeObject(string str)
        {
            byte[] byt = Convert.FromBase64String(str);
            object obj = null;
            using (Stream stream = new MemoryStream(byt, 0, byt.Length))
            {
                IFormatter formatter = new BinaryFormatter();
                obj = formatter.Deserialize(stream);
            }
            return obj;
        }
        public static string getWebConfig(string key)
        {
            return System.Configuration.ConfigurationManager.AppSettings[key].ToString();
        }
        public static string GetClientBrowserVersions()
        {
            string browserVersions = string.Empty;
            HttpBrowserCapabilities hbc = HttpContext.Current.Request.Browser;
            string browserType = hbc.Browser.ToString();     //获取浏览器类型
            string browserVersion = hbc.Version.ToString();    //获取版本号
            browserVersions = browserType + browserVersion;
            return browserVersions;
        }
        public static bool IsMoblie()
        {
            string agent = (System.Web.HttpContext.Current.Request.UserAgent + "").ToLower().Trim();

            if (agent == "" ||
            agent.IndexOf("mobile") != -1 ||
            agent.IndexOf("mobi") != -1 ||
            agent.IndexOf("nokia") != -1 ||
            agent.IndexOf("samsung") != -1 ||
            agent.IndexOf("sonyericsson") != -1 ||
            agent.IndexOf("mot") != -1 ||
            agent.IndexOf("blackberry") != -1 ||
            agent.IndexOf("lg") != -1 ||
            agent.IndexOf("htc") != -1 ||
            agent.IndexOf("j2me") != -1 ||
            agent.IndexOf("ucweb") != -1 ||
            agent.IndexOf("opera mini") != -1 ||
            agent.IndexOf("mobi") != -1 ||
            agent.IndexOf("android") != -1 ||
            agent.IndexOf("iphone") != -1)
            {
                //客户瑞是手机
                return true;
            }

            return false;
        }

        #region 获取URL参数类
        public static string get_q(string val)
        {
            if (string.IsNullOrEmpty(val))
            {
                return null;
            }
            else
            {
                if (string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.QueryString[val]))
                {
                    return null;
                }
                else
                {
                    return System.Web.HttpContext.Current.Request.QueryString[val].ToString();
                }
            }
        }
        public static string get_f(string val)
        {
            if (string.IsNullOrEmpty(val))
            {
                return null;
            }
            else
            {
                if (string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Form[val]))
                {
                    return null;
                }
                else
                {
                    return System.Web.HttpContext.Current.Request.Form[val].ToString();
                }
            }
        }
        public static string get_p(string val)
        {
            if (string.IsNullOrEmpty(val))
            {
                return null;
            }
            else
            {
                if (string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Params[val]))
                {
                    return null;
                }
                else
                {
                    return System.Web.HttpContext.Current.Request.Params[val].ToString();
                }
            }
        }
        #endregion
        
        public static string trimString(string value)
        {
            string ret = null;
            if (null != value)
            {
                ret = value;
                if (ret.Length == 0)
                {
                    ret = null;
                }
            }
            return ret;
        }
        /// <summary>
        /// 获取时间对比结果
        /// </summary>
        /// <returns></returns>
        public static bool TimeSpans(DateTime dt1,DateTime dt2)
        {
            return DateTime.Compare(dt1, dt2) > 0 ? true : false;
        }
        /// <summary>
        /// MD5
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string md5(string str)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
        }
        /// <summary>
        /// 作用：array转xml
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static string ArrayToXml(Dictionary<string, string> arr)
        {
            
            string xml = "<xml>";
            int fd;
            foreach (var s in arr)
            {
                if (!int.TryParse(s.Value, out fd))
                    xml += "<" + s.Key + "><![CDATA[" + s.Value + "]]></" + s.Key + ">";
                else
                    xml += "<" + s.Key + ">" + s.Value + "</" + s.Key + ">";
            }
            xml += "</xml>";
            return xml;
        }


        /// <summary>
        /// 读取指定路径和节点的串联值
        /// 使用示列:
        /// XMLProsess.Read(path, "/Node", "")
        /// XMLProsess.Read(path, "/Node/Element[@Attribute='Name']")
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名，非空时返回该属性值，否则返回串联值</param>
        public static string ReadXmlNode(string xml, string node)
        {
            string value = "";
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                XmlNode xn = doc.SelectSingleNode(node);
                value = xn.InnerText;
            }
            catch { }
            return value;
        }

        /// <summary>
        /// 作用：将xml转为array
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static Dictionary<string, object> XmlToArray(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            string json = JsonConvert.SerializeXmlNode(doc);
            Dictionary<string, object> array_data = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
            return array_data;
        }
        /// <summary>
        /// 作用：以post方式提交xml到对应的接口url
        /// </summary>
        /// <param name="url"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string postXmlCurl(string url, string data)
        {
            HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(url);
            hwr.Method = "POST";
            Stream stream = hwr.GetRequestStream();
            StreamWriter sw = new StreamWriter(stream, System.Text.Encoding.UTF8);
            sw.Write(data);
            sw.Close();
            stream = hwr.GetResponse().GetResponseStream();
            StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
            string ret = sr.ReadToEnd();
            HttpContext.Current.Response.Write(ret);
            WeChat_Pub.postvalue = ret;
            sr.Close();
            return ret;
        }
        /// <summary>
        /// 作用：产生随机字符串，不长于32位
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string CreatNonceStr(int length = 32)
        {
            string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
            string str = "";
            var r = new Random();
            for (int i = 0; i < length; i++)
            {
                str += chars.Substring(r.Next(0, chars.Length - 1), 1);
            }
            return str;
        }
        /// <summary>
        /// 	作用：格式化参数，签名过程需要使用
        /// </summary>
        /// <param name="paraMap"></param>
        /// <returns></returns>
        public static string formatBizQueryParaMap(Dictionary<string, string> paraMap)
        {
            string buff = "";
            var al = new ArrayList(paraMap.Keys);
            al.Sort();
            foreach (string k in al)
            {
                buff += k + "=" + paraMap[k] + "&";
            }
            string reqPar = null;
            if (buff.Length > 0)
            {
                reqPar = buff.Substring(0, buff.Length - 1);
            }
            return reqPar;
        }
        /// <summary>
        /// 是否需要重新获取AccessToken 
        /// True 为 需要重新获取
        /// </summary>
        /// <returns></returns>
        public static bool CheckRefTime(int MemberId)
        {
            //Log("ReTime", Wx_Conf.RefreshTime.ToString());
            //Log("times", TimeSpans(DateTime.Parse("2015/10/28 0:40:06"), DateTime.Parse("2015/10/28 2:40:06")).ToString());
            //System.IO.File.WriteAllText(HttpContext.Current.Server.MapPath("~/flag.txt"), (DateTime.Compare(DateTime.Now, Wx_Conf.RefreshTime) > 0).ToString());
            if (DateTime.Compare(DateTime.Now, WeChatConf.RefreshTime(MemberId)) > 0) //如果当前时间晚于设置的时间 则需要重新获取
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }


    public class WeChat_Pub : WeChatCommon
    {
        public static string postvalue;
        public Dictionary<string, string> Parameters = new Dictionary<string, string>();
        /// <summary>
        /// 作用：生成签名
        /// </summary>
        /// <param name="Obj"></param>
        /// <returns></returns>
        public string getSign(Dictionary<string, string> Obj)
        {
            foreach (var k in Obj)
            {
                Parameters[k.Key] = k.Value;
            }
            string s = formatBizQueryParaMap(Parameters);
            //echo '【string1】'.$String.'</br>';
            //签名步骤二：在string后加入KEY
            s += "&key=" + WeChatMemory.MemberInfo(WeChatConf.MemberId()).APPKEY;
            //签名步骤三：MD5加密
            s = md5(s);
            //签名步骤四：所有字符转为大写
            string result_ = s.ToUpper();
            return result_;
        }
    }

    public class WxPay_Client_Pub : WeChat_Pub
    {
        public Dictionary<string, string> parameters = new Dictionary<string, string>();//请求参数，类型为关联数组
        public string response = string.Empty;//微信返回的响应
        public Dictionary<string, object> result = new Dictionary<string, object>();//返回参数，类型为关联数组
        public string url = string.Empty;//接口链接
        public int curl_timeout = 0;//curl超时时间

        /// <summary>
        /// 作用：设置请求参数
        /// </summary>
        /// <param name="parameterName"></param>
        /// <param name="parameterValue"></param>
        public void setParameter(string parameterName, string parameterValue)
        {
            this.parameters[trimString(parameterName)] = trimString(parameterValue);
        }

        /// <summary>
        /// 作用：设置标配的请求参数，生成签名，生成接口参数xml
        /// </summary>
        /// <returns></returns>
        public string createXml()
        {
            parameters["appid"] = WeChatMemory.MemberInfo(WeChatConf.MemberId()).APPID;//公众账号ID
            parameters["mch_id"] = WeChatMemory.MemberInfo(WeChatConf.MemberId()).MCHID;//商户号
            parameters["nonce_str"] = CreatNonceStr();//随机字符串
            parameters["sign"] = getSign(parameters);//签名
            return ArrayToXml(parameters);
        }

        /// <summary>
        /// 作用：post请求xml
        /// </summary>
        /// <returns></returns>
        public string postXml()
        {
            string xml = createXml();
            return postXmlCurl(url, xml);
        }

        /// <summary>
        /// 	作用：获取结果，默认不使用证书
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, object> getResult()
        {
            postXml();
            return XmlToArray(response);
        }
    }

    public class UnifiedOrder_Pub : WxPay_Client_Pub
    {
        public UnifiedOrder_Pub()
        {
            //设置接口链接
            url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            //设置curl超时时间
            curl_timeout = WeChatConf.CURL_TIMEOUT;
        }

        /**
         * 生成接口参数xml
         */
        public string createXml()
        {
            try
            {
                //检测必填参数
                if (parameters["out_trade_no"] == null)
                {
                    throw new Exception("缺少统一支付接口必填参数out_trade_no！<br>");
                }
                else if (parameters["body"] == null)
                {
                    throw new Exception("缺少统一支付接口必填参数body！<br>");
                }
                else if (parameters["total_fee"] == null)
                {
                    throw new Exception("缺少统一支付接口必填参数total_fee！<br>");
                }
                else if (parameters["notify_url"] == null)
                {
                    throw new Exception("缺少统一支付接口必填参数notify_url！<br>");
                }
                else if (parameters["trade_type"] == null)
                {
                    throw new Exception("缺少统一支付接口必填参数trade_type！<br>");
                }
                else if (parameters["trade_type"] == "JSAPI" &&
                   parameters["openid"] == null)
                {
                    throw new Exception("统一支付接口中，缺少必填参数openid！trade_type为JSAPI时，openid为必填参数！<br>");
                }
                parameters["appid"] = WeChatMemory.MemberInfo(WeChatConf.MemberId()).APPID;//公众账号ID
                parameters["mch_id"] = WeChatMemory.MemberInfo(WeChatConf.MemberId()).MCHID;//商户号
                parameters["spbill_create_ip"] = "";//终端ip	    
                parameters["nonce_str"] = CreatNonceStr();//随机字符串
                parameters["sign"] = getSign(parameters);//签名
                return ArrayToXml(parameters);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /**
         * 获取prepay_id
         */
        public string getPrepayId()
        {
            postXml();
            result = XmlToArray(response);
            string prepay_id = result["prepay_id"].ToString();
            return prepay_id;
        }

    }

    public class WeChatApi : WeChat_Pub 
    {
        /// <summary>
        /// 获取用来换OpenId的Code
        /// </summary>
        //public string Code = "";
        //public string Token = "";
        /// <summary>
        /// 获取临时二维码Ticket
        /// </summary>
        /// <param name="expire_seconds">2592000=30天</param>
        /// <param name="scene_id">自定义值 32位非0整型</param>
        /// <returns></returns>
        public static WeChatModel.qrTicket getQRCode(int expire_seconds, int scene_id, int MemberId)
        {
            string jsonstr = "{\"expire_seconds\": " + expire_seconds + ", \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": " + scene_id + "}}}";
            string result = HttpPost(string.Format(WeChat_Url.GetQRCode, WeChatConf.AccessToken(MemberId)), jsonstr);
            return  JsonConvert.DeserializeObject<WeChatModel.qrTicket>(result);
        }
        /// <summary>
        /// 获取永久二维码Ticket
        /// </summary>
        /// <param name="scene">自定义值 obj类型 只支持字符串和整型 目前建议传整型 str暂未测试</param>
        /// <returns></returns>
        public static WeChatModel.qrTicket getQRCode(object scene, int MemberId)
        {
            bool IsInt32 = (scene.GetType().Name.ToLower() == "int32");
            string jsonstr = "";
            if (IsInt32) //整型二维码
            {
                jsonstr = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": " + scene + "}}}";
            }
            else
            { //字符串二维码
                jsonstr = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"" + scene + "\"}}}";
            }
            string result = HttpPost(string.Format(WeChat_Url.GetQRCode, WeChatConf.AccessToken(MemberId)), jsonstr);
            return JsonConvert.DeserializeObject<WeChatModel.qrTicket>(result);
        }
        
        /// <summary>
        /// 通过curl向微信提交code，以获取openid
        /// </summary>
        /// <returns></returns>
        public static string getOpenid(int MemberId,string Code)
        {
            Model.wx_member WeChat_Member = WeChatMemory.MemberInfo(MemberId); //= new BLL.Wx_Member().GetModel(MemberId);
            string GetOpenIdUrl = string.Format(WeChat_Url.GetOpenId, WeChat_Member.APPID, WeChat_Member.APPSECRET, Code);
            string result = WeChatCommon.HttpGet(GetOpenIdUrl);
            System.Collections.Generic.Dictionary<string, object> dic_token = Newtonsoft.Json.JsonConvert.DeserializeObject<System.Collections.Generic.Dictionary<string, object>>(result);
            return dic_token["openid"].ToString();
        }

        /// <summary>
        /// 根据OpenId 获取用户信息
        /// </summary>
        /// <param name="MemberId"></param>
        /// <param name="openid"></param>
        /// <returns></returns>
        public static WeChatModel.userInfo GetUserInfo(int MemberId, string openid)
        {
            try
            {
                string result = WeChatCommon.HttpGet(string.Format(WeChat_Url.GetUserInfo, GetAccessToken(MemberId), openid));
                //WeChatCommon.Log("GetUserInfo", result);
                WeChatModel.userInfo UserInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<WeChatModel.userInfo>(result);
                return UserInfo;
            }
            catch (Exception ex)
            {
                //WeChatCommon.Log("Error", ex.ToString());
                return null;
            }
        }

        /// <summary>
        /// 作用：获取全局AccessToken
        /// 全局都必须从这里获取AccessToken
        /// </summary>
        /// <returns></returns>
        public static string GetAccessToken(int MemberId)
        {
            string thisAccessToken = "";
            thisAccessToken = WeChatCache.GetValue(MemberId + "_AccessToken") as string;
            if (string.IsNullOrEmpty(thisAccessToken))
            {
                try
                {
                    Model.wx_member member = WeChatMemory.MemberInfo(MemberId);

                    string url = string.Format(WeChat_Url.GetAccessToken, member.APPID, member.APPSECRET);
                    string result = WeChatCommon.HttpGet(url);
                    System.Collections.Generic.Dictionary<string, object> dic_token = Newtonsoft.Json.JsonConvert.DeserializeObject<System.Collections.Generic.Dictionary<string, object>>(result);

                    //将AccessToken存起来
                    int expires_in = Convert.ToInt32(dic_token["expires_in"].ToString());//拿到过期时间
                    string access_token = dic_token["access_token"].ToString();
                    WeChatCache.Insert_NoSliding_Rank(MemberId + "_AccessToken", access_token, expires_in - 200, WeChatCache.GetRank(6));
                    WeChatCache.Insert_NoSliding_Rank(MemberId + "_RefreshTime", expires_in, expires_in - 200, WeChatCache.GetRank(6));

                    //更新完成后从缓存里面拿数据
                    thisAccessToken = WeChatCache.GetValue(MemberId + "_AccessToken") as string;

                    //更新数据至数据库_ 后期稳定后不需要写入数据库 , 暂时保留
                    new BLL.Wx_Member().UpdateField(string.Format(" Id={0} ", MemberId), string.Format(" AccessToken='{0}',RefreshTime='{1}' ", dic_token["access_token"].ToString(), DateTime.Now.AddSeconds(expires_in - 200).ToString()));

                    //写日志
                    //WeChatCommon.Log("AccessToken", "AccessToken最近一次获取时间：" + DateTime.Now.ToString() + ", RefreshTime：" + WeChatConf.RefreshTime(MemberId).ToString());
                }
                catch (Exception ex)
                {
                    WeChatCommon.Log("GetAccessToken", MemberId + ex.ToString());
                }
            }
            return thisAccessToken; //WeChatConf.AccessToken(MemberId);
        }

        /// <summary>
        /// 获取JSAPI凭据  不用存储在数据库
        /// </summary>
        /// <param name="MemberId"></param>
        /// <returns></returns>
        public static string GetJsApiTicket(int MemberId)
        {
            string thisJSApiTicket = "";
            thisJSApiTicket = WeChatCache.GetValue(MemberId + "_JsApiTicket") as string;
            //WeChatCommon.Log("thisJSApiTicket", thisJSApiTicket);
            //WeChat.WeChatCommon.WeChatLog(string.IsNullOrEmpty(thisJSApiTicket).ToString());
            if (string.IsNullOrEmpty(thisJSApiTicket))
            {
                try
                {
                    Model.wx_member member = WeChatMemory.MemberInfo(MemberId);
                    string url = string.Format(WeChat_Url.GetJSApiTicket, GetAccessToken(MemberId));
                    string result = WxSDK.WeChatCommon.HttpGet(url);
                    System.Collections.Generic.Dictionary<string, object> dic_token = Newtonsoft.Json.JsonConvert.DeserializeObject<System.Collections.Generic.Dictionary<string, object>>(result);

                    //将AccessToken存起来
                    int expires_in = Convert.ToInt32(dic_token["expires_in"].ToString());//拿到过期时间
                    string ticket = dic_token["ticket"].ToString();
                    thisJSApiTicket = ticket;
                    WeChatCache.Insert_NoSliding_Rank(MemberId + "_JsApiTicket", ticket, expires_in - 200, WeChatCache.GetRank(6));
                    WeChatCache.Insert_NoSliding_Rank(MemberId + "_JsApiTicket_RefreshTime", expires_in, expires_in - 200, WeChatCache.GetRank(6));
                }
                catch (Exception ex)
                {
                    //WeChatCommon.Log("GetJsApiTicket", MemberId + ex.ToString());
                }
            }
            return thisJSApiTicket;
        }

    }

    /// <summary>
    /// 获取微信公众号配置相关 正在修改
    /// </summary>
    public class WeChatConf : WeChatCommon
    {
        /// <summary>
        /// 微信公众号的配置ID
        /// </summary>
        //public static int MemberId() { return int.Parse(getWebConfig("WxMemberId")); }
        public static int MemberId() {
            try
            {
                string mid = get_q("mid");
                
                if (string.IsNullOrEmpty(mid))
                {
                    mid = System.Configuration.ConfigurationManager.AppSettings["WxMemberId"];
                    if (string.IsNullOrEmpty(mid))
                    {
                        throw new Common.WxException("memberId为空");
                    }
                    else {
                        return int.Parse(mid.Trim());
                    }
                }
                else
                {
                    return int.Parse(mid.Trim());
                }
            }
            catch (Exception ex)
            {
                throw new Common.WxException(ex.Message);
            }
            
        }
        /// <summary>
        /// 微信公众号的授权方式
        /// </summary>
        //public static string Scope() { return getWebConfig("WxScope"); }

        /// <summary>
        /// APPID
        /// </summary>
        //public static string APPID = getWebConfig("WX_APPID");
        /// <summary>
        /// 受理商ID，身份标识
        /// </summary>
        //public static string MCHID = getWebConfig("WX_MCHID"); //"1227012902";
        /// <summary>
        /// 商户支付密钥Key。审核通过后，在微信发送的邮件中查看
        /// </summary>
        //public static string KEY = getWebConfig("WX_KEY");
        /// <summary>
        /// JSAPI接口中获取openid，审核后在公众平台开启开发模式后可查看
        /// </summary>
        //public static string APPSECRET = getWebConfig("WX_APPSECRET");//"f53b1d7a68903799b6cb8b7e566f21dc";

        /// <summary>
        /// 全局AccessToken
        /// </summary>
        public static string AccessToken(int MemberId){
            return WeChatApi.GetAccessToken(MemberId);
        }
        /// <summary>
        /// 全局AccessToken 刷新时间  7200
        /// </summary>
        public static DateTime RefreshTime(int MemberId)
        {
            try
            {
                return Convert.ToDateTime(HttpContext.Current.Application[MemberId+"_RefreshTime"]);
            }
            catch
            {
                return new BLL.Wx_Member().GetModel(MemberId).RefreshTime;
            }
        }

        //=======【JSAPI路径设置】===================================
        /// <summary>
        /// 获取access_token过程中的跳转uri，通过跳转将code传入jsapi支付页面
        /// </summary>
        //public static string REDIRECT_URL = getWebConfig("WX_REDIRECT_URL");//"http://event.jbaschi.com.cn/index.aspx";
        //=======【异步通知url设置】===================================
        /// <summary>
        /// 异步通知url，商户根据实际开发过程设定
        /// </summary>
        //public static string NOTIFY_URL = getWebConfig("WX_NOTIFY_URL"); //"http://" + HttpContext.Current.Request.Url.Host + "/pay/notify_url.aspx";
        //=======【curl超时设置】===================================
        /// <summary>
        /// 本例程通过curl使用HTTP POST方法，此处可修改其超时时间，默认为30秒
        /// </summary>
        public const int CURL_TIMEOUT = 30;

    }

    /// <summary>
    /// 微信地理位置
    /// </summary>
    public class WeChatLocation : WeChatCommon {
        
        public class wechat_location {
            public string status { get; set; }
            public result result;
        }
        public class result
        {
            public location location;
            public string formatted_address { get; set; }
            public string business { get; set; }
            public addressComponent addressComponent;
            //
            //
            public string sematic_description { get; set; }
            public string cityCode { get; set; }
        }
        public class location
        {
            public string lng { get; set; }
            public string lat { get; set; }
        }
        public class addressComponent
        {
            public string adcode { get; set; }
            public string city { get; set; }
            public string country { get; set; }
            public string direction { get; set; }
            public string distance { get; set; }
            public string district { get; set; }
            public string province { get; set; }
            public string street { get; set; }
            public string street_number { get; set; }
            public string country_code { get; set; }
        }
        /// <summary>
        /// 百度Geocoding API 地址转换 经纬度转换为地址
        /// </summary>
        /// <param name="lat">纬度值</param>
        /// <param name="lng">经度值</param>
        public static wechat_location GetLocation(string lat, string lng)
        {
            string url = "http://api.map.baidu.com/geocoder/v2/";
            string par = string.Format("?ak=ThDG3c2RjvaGgkWMnfBGMfmbI6k5xGjT&location={0},{1}&output=json&pois=0",lat,lng);
            string jsonData = HttpGet(url + par);
            wechat_location location = (wechat_location)JsonConvert.DeserializeObject(jsonData, typeof(wechat_location));
            return location;
        }

    }

    /// <summary>
    /// 聚合机器人
    /// </summary>
    public class JuHeRobot {

        //private static Third.API.Model.JuheModel.Robot_Parameter robot = new Third.API.Model.JuheModel.Robot_Parameter();

        //public static string Robot(string info, string userid) {
        //    robot.info = info;
        //    robot.userid = userid;
        //    robot.key = "68bf5babd5be41681112f6b56aaae89d";
        //    return Third.API.API.JuHeAPI.JuHe_Robot(robot).result.text;
            
        //}

    }
}